package app

import (
	"context"
	"fmt"
	"regexp"

	// "io/ioutil"
	"net/http"

	"github.com/go-chi/chi/v5"
	"github.com/go-chi/render"
	"go.uber.org/zap"
	"originforce.club/bilin-mock/conf"
	"originforce.club/bilin-mock/internal/dao"
	sqlc "originforce.club/bilin-mock/internal/db/sqlc"
	appRender "originforce.club/bilin-mock/internal/rest/render"
	"originforce.club/bilin-mock/internal/util"
)

type MockRouter struct {
	slog *zap.SugaredLogger
	dao  *db.PgDao
	vars *conf.VarsSection
	r    chi.Router
}

// New initialization
func New(
	slog *zap.SugaredLogger,
	dao *db.PgDao,
	vars *conf.VarsSection,
) (r chi.Router) {
	s := &MockRouter{
		slog: slog.With("module", "MockRouter"),
		dao:  dao,
		vars: vars,
		r:    chi.NewRouter(),
	}
	s.register()
	return s.r
}

func (s *MockRouter) register() {
	s.r.Use(s.handleParentCtx)
	// s.r.Get("/*", s.mockMthod) handleFunc 
	s.r.Handle("/*", s) // handler

}
func (s *MockRouter) handleParentCtx(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		appID := chi.URLParam(r, "app_id")
		if util.IsEmpty(appID) {
			render.Render(w, r, appRender.ErrInvalidRequest(fmt.Errorf("app_id")))
			return
		}
		s.slog.Infof("app_id=>%s", appID)
		ctx := context.WithValue(r.Context(), "app_id", appID)
		next.ServeHTTP(w, r.WithContext(ctx))
	})
}



type MatchApiApiPredictor struct {
	slog   *zap.SugaredLogger
	appID  string
	path   string
}

func (s *MatchApiApiPredictor) Predict(api *sqlc.AppApi) bool {
	matched, _ := regexp.MatchString(fmt.Sprintf("/%s%s", s.appID, api.PathPattern), s.path)
	return matched
}


func (s *MockRouter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	appID := ctx.Value("app_id").(string)
	// pagerPtr := ctx.Value(util.PagerKey{}).(*util.Pager)
	apis, err := s.dao.Q.ListAppApisByAppIDAndMethod(ctx, sqlc.ListAppApisByAppIDAndMethodParams{
		Status: 1,
		AppID:  appID,
		Method: r.Method,
	})
	if err != nil {
		render.Render(w, r, appRender.ErrRender(err))
		return
	}
	apiPtr := db.Find[sqlc.AppApi](apis, &MatchApiApiPredictor{
		slog:   s.slog,
		appID:  appID,
		path:   r.URL.Path,
	})
	if apiPtr == nil {
		render.Render(w, r, appRender.ErrInvalidPath(fmt.Errorf("no match path")))
		return
	}

	render.JSON(w, r, apiPtr.Result)
}

// func (s *MockRouter) mockMthod(w http.ResponseWriter, r *http.Request) {
// 	ctx := r.Context()
// 	appID := ctx.Value("app_id").(string)
// 	// pagerPtr := ctx.Value(util.PagerKey{}).(*util.Pager)
// 	apis, err := s.dao.Q.ListAppApisByAppIDAndMethod(ctx, sqlc.ListAppApisByAppIDAndMethodParams{
// 		Status: 1,
// 		AppID:  appID,
// 		Method: r.Method,
// 	})
// 	if err != nil {
// 		render.Render(w, r, appRender.ErrRender(err))
// 		return
// 	}
// 	apiPtr := db.Find[sqlc.AppApi](apis, &MatchApiApiPredictor{
// 		slog:   s.slog,
// 		appID:  appID,
// 		method: r.Method,
// 		path:   r.URL.Path,
// 	})
// 	if apiPtr == nil {
// 		render.Render(w, r, appRender.ErrInvalidPath(fmt.Errorf("no match path")))
// 		return
// 	}

// 	render.JSON(w, r, apiPtr.Result)
// }
